package com.sec.android.app.myfiles.feature.Hover;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.net.Uri;
import android.provider.MediaStore;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.sec.android.app.myfiles.R;
import com.sec.android.app.myfiles.fragment.AbsMyFilesFragment;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;

import java.io.IOException;

public class VideoHoverView extends PlayableMediaHoverView {
    private SurfaceView mSurfaceView = null;
    private SurfaceHolder mSurfaceHolder = null;
    private ImageView mPreviewThumbnail = null;
    private AudioManager mAudioManager = null;

    private boolean mHasAudioFocus = false;
    private SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() {
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        }

        public void surfaceCreated(SurfaceHolder holder) {
            mSurfaceHolder = holder;
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            mSurfaceHolder = null;

            mIsStarted = false;
            if (mMediaPlayer != null) {
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
        }
    };
    private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_LOSS:
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    mHandler.sendEmptyMessage(HoverMsg.MSG_DISMISS_POPUP);
                    break;
            }
        }
    };

    public VideoHoverView(Activity activity, AbsMyFilesFragment fragment, FileRecord record) {
        super(activity, fragment, record);
        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
    }

    @Override
    protected void initViews() {
        super.initViews();
        mLayout = (LinearLayout) View.inflate(mContext, R.layout.hover_video_view, null);
        if (mLayout != null) {
            mSurfaceView = (SurfaceView) mLayout.findViewById(R.id.airview_preview_video);

            if (mDialog != null && mSurfaceView != null) {
                mSurfaceHolder = mSurfaceView.getHolder();
                mSurfaceHolder.addCallback(mSHCallback);
                mDialog.setContentView(mLayout);
                setDataSource();
                setVideoView();
                setDialogPosition();
                initHoverButton();
                initOverlayIcons();
                mLayout.setOnHoverListener(mLayoutListener);
            }
        }
    }

    private void setDialogPosition() {
        if (mView != null) {
            android.view.ViewGroup.LayoutParams surfaceParams = mSurfaceView.getLayoutParams();

            // Grid view 2x,3x,4x Thumbnail size are different. so popup window displays at wrong position.
            // Margin values considered 4 cases. Thumbnail view's height[or width] is larger or smaller than popup window's width[or height].
            int leftMargin = surfaceParams.width - mView.getWidth() > 0 ? -1 * ((surfaceParams.width - mView.getWidth()) / 2) : (mView.getWidth() - surfaceParams.width) / 2;
            int topMargin = mView.getHeight() / 4;

            setDialogPosition(leftMargin, topMargin);
        }
    }

    private void playVideo() {
        if (mSurfaceHolder == null) {
            return;
        }

        if (mMediaPlayer != null) {
            mMediaPlayer.release();
            mMediaPlayer = null;
        }

        if (!requestAudioFocus()) {
            mHandler.sendEmptyMessage(HoverMsg.MSG_DISMISS_POPUP);
            return;
        }

        if (mPreviewThumbnail != null) {
            mPreviewThumbnail.setImageBitmap(null);
        }

        try {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnPreparedListener((new MediaPlayer.OnPreparedListener() {
                public void onPrepared(MediaPlayer player) {
                    player.start();
                }
            }));
            mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                public void onSeekComplete(MediaPlayer player) {
                    player.start();
                }
            });
            mMediaPlayer.setOnVideoSizeChangedListener(null);
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                public void onCompletion(MediaPlayer player) {
                    player.release();
                    removeDelayedMessage();
                    mHandler.sendEmptyMessage(HoverMsg.MSG_DISMISS_POPUP);
                }
            });
            mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                public boolean onError(MediaPlayer player, int arg1, int arg2) {
                    player.reset();
                    removeDelayedMessage();
                    mHandler.sendEmptyMessage(HoverMsg.MSG_DISMISS_POPUP);
                    return false;
                }
            });

            mMediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                public boolean onInfo(final MediaPlayer mp, final int what, final int extra) {
                    switch (what) {
                        case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
                        case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
                        case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
                        case MediaPlayer.MEDIA_INFO_UNKNOWN:
                            break;
                        default:
                            break;
                    }
                    return false;
                }
            });

            if (mFilePath == null) {
                mHandler.sendEmptyMessage(HoverMsg.MSG_DISMISS_POPUP);
                return;
            }

            if (mFilePath.startsWith("content://")) {
                mMediaPlayer.setDataSource(mContext, Uri.parse(mFilePath));
            } else {
                mMediaPlayer.setDataSource(mFilePath);
            }
            setMediaPlayerParameter();

            if (mSurfaceHolder != null) {
                mMediaPlayer.setDisplay(mSurfaceHolder);
            }

            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.setScreenOnWhilePlaying(true);
            mMediaPlayer.prepareAsync();
        } catch (IOException ex) {
            Log.e(this, "playVideo - IOException");
        } catch (IllegalStateException ex) {
            Log.e(this, "playVideo - IllegalStateException");
        } catch (IllegalArgumentException ex) {
            Log.e(this, "playVideo - IllegalArgumentException");
        }

        mIsStarted = true;
    }

    private void setMediaPlayerParameter() {
        // Regarding PLM issue P170620-04417,
        // To turn off HDR on VideoHoverView (Requested by su46.park)
    }

    private boolean requestAudioFocus() {
        if (!mHasAudioFocus) {
            int ret;
            if (mAudioManager.isMusicActive()) {
                ret = mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            } else {
                ret = mAudioManager.requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
            }

            if (ret == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                mHasAudioFocus = true;
            } else {
                mHasAudioFocus = false;
            }
        }
        return mHasAudioFocus;
    }

    private void abandonAudioFocus() {
        if (mHasAudioFocus) {
            mHasAudioFocus = false;
            mAudioManager.abandonAudioFocus(mAudioFocusListener);
        }
    }


    private void setVideoView() {
        float videoSizeWidth = mMediaPlayer.getVideoWidth();
        float videoSizeHeight = mMediaPlayer.getVideoHeight();

        android.view.ViewGroup.LayoutParams params = mSurfaceView.getLayoutParams();
        float ratio = getRatio(videoSizeWidth, videoSizeHeight);
        params.width = (int) (videoSizeWidth * ratio);
        params.height = (int) (videoSizeHeight * ratio);
        mSurfaceView.setLayoutParams(params);

        mPreviewThumbnail = (ImageView) mLayout.findViewById(R.id.airview_preview_image);
        mPreviewThumbnail.setLayoutParams(params);
        Bitmap ret = android.media.ThumbnailUtils.createVideoThumbnail(mRecord.getFullPath(), MediaStore.Video.Thumbnails.MINI_KIND);
        if (ret == null) {
            Log.d(this, "record " + mRecord.getName() + " ret = null");
        }
        mPreviewThumbnail.setImageBitmap(ret);
    }

    private void setDataSource() {
        try {
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(mFilePath);
            setMediaPlayerParameter();
            mMediaPlayer.prepare();
        } catch (IllegalArgumentException e) {
            Log.e(this, "IllegalArgumentException:" + e.toString());
        } catch (SecurityException e) {
            Log.e(this, "SecurityException:" + e.toString());
        } catch (IllegalStateException e) {
            Log.e(this, "IllegalStateException:" + e.toString());
        } catch (IOException e) {
            Log.e(this, "IOException:" + e.toString());
        }
    }

    @Override
    protected void initHoverButton() {
        super.initHoverButton();
        if (mPlayButton != null) {
            mPlayButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    if (mMediaPlayer.isPlaying()) {
                        mMediaPlayer.pause();
                        mPlayButton.setBackground(mContext.getDrawable(R.drawable.hover_play_btn));
                        mPlayButton.setContentDescription(mContext.getResources().getString(R.string.hover_play));
                    } else {
                        if (mIsStarted) {
                            mMediaPlayer.start();
                        } else {
                            playVideo();
                        }
                        mPlayButton.setBackground(mContext.getDrawable(R.drawable.hover_pause_btn));
                        mPlayButton.setContentDescription(mContext.getResources().getString(R.string.hover_pause));
                    }
                }
            });
        }
    }

    @Override
    public void dismissPopup() {
        super.dismissPopup();
        if (mDialog != null && mDialog.isShowing()) {
            abandonAudioFocus();
        }
        if (mSurfaceHolder != null) {
            mSurfaceHolder = null;
        }
        mIsStarted = false;
    }
}
